form builder

安装量: 46
排名: #15938

安装

npx skills add https://github.com/eddiebe147/claude-settings --skill 'Form Builder'

Form Builder The Form Builder skill automates the creation of fillable forms, surveys, questionnaires, and interactive documents. It handles various form types including registration forms, feedback surveys, applications, intake forms, and assessment tools. The skill supports multiple output formats (PDF with fillable fields, HTML forms, Google Forms integration) with validation rules, conditional logic, and data collection capabilities. Generate professional forms with proper field types, validation, styling, and submission handling for any data collection need. Core Workflows Workflow 1: Create PDF Fillable Form Purpose: Generate a PDF with interactive fillable fields Steps: Define form structure and fields Set field types (text, checkbox, radio, dropdown, date) Add validation rules for each field Configure field properties (required, maxLength, etc.) Apply styling and layout Add instructions and help text Generate PDF with fillable fields Test form functionality Implementation: const { PDFDocument , PDFTextField , PDFCheckBox , PDFDropdown , rgb } = require ( 'pdf-lib' ) ; const fs = require ( 'fs' ) ; async function createFillablePDFForm ( formData , outputPath ) { const pdfDoc = await PDFDocument . create ( ) ; const page = pdfDoc . addPage ( [ 612 , 792 ] ) ; // Letter size const { width , height } = page . getSize ( ) ; const fontSize = 11 ; const labelFontSize = 10 ; // Add title page . drawText ( formData . title , { x : 50 , y : height - 50 , size : 18 , color : rgb ( 0.2 , 0.2 , 0.2 ) } ) ; // Add instructions if ( formData . instructions ) { page . drawText ( formData . instructions , { x : 50 , y : height - 80 , size : 10 , color : rgb ( 0.4 , 0.4 , 0.4 ) , maxWidth : width - 100 } ) ; } let currentY = height - 120 ; // Add form fields for ( const field of formData . fields ) { // Draw field label page . drawText ( field . label + ( field . required ? ' *' : '' ) , { x : 50 , y : currentY , size : labelFontSize , color : rgb ( 0 , 0 , 0 ) } ) ; currentY -= 25 ; // Create field based on type switch ( field . type ) { case 'text' : case 'email' : case 'number' : const textField = pdfDoc . getForm ( ) . createTextField ( field . name ) ; textField . addToPage ( page , { x : 50 , y : currentY , width : 300 , height : 20 , borderColor : rgb ( 0.5 , 0.5 , 0.5 ) , borderWidth : 1 } ) ; if ( field . placeholder ) { textField . setText ( field . placeholder ) ; } if ( field . maxLength ) { textField . setMaxLength ( field . maxLength ) ; } break ; case 'textarea' : const textArea = pdfDoc . getForm ( ) . createTextField ( field . name ) ; textArea . addToPage ( page , { x : 50 , y : currentY - 40 , width : 500 , height : 60 , borderColor : rgb ( 0.5 , 0.5 , 0.5 ) , borderWidth : 1 } ) ; textArea . enableMultiline ( ) ; currentY -= 40 ; break ; case 'checkbox' : field . options . forEach ( ( option , index ) => { const checkbox = pdfDoc . getForm ( ) . createCheckBox ( ${ field . name } _ ${ index } ) ; checkbox . addToPage ( page , { x : 50 , y : currentY - ( index * 20 ) , width : 12 , height : 12 , borderColor : rgb ( 0.5 , 0.5 , 0.5 ) , borderWidth : 1 } ) ; page . drawText ( option , { x : 70 , y : currentY - ( index * 20 ) + 2 , size : 10 , color : rgb ( 0 , 0 , 0 ) } ) ; } ) ; currentY -= field . options . length * 20 ; break ; case 'radio' : const radioGroup = pdfDoc . getForm ( ) . createRadioGroup ( field . name ) ; field . options . forEach ( ( option , index ) => { radioGroup . addOptionToPage ( option , page , { x : 50 , y : currentY - ( index * 20 ) , width : 12 , height : 12 , borderColor : rgb ( 0.5 , 0.5 , 0.5 ) , borderWidth : 1 } ) ; page . drawText ( option , { x : 70 , y : currentY - ( index * 20 ) + 2 , size : 10 , color : rgb ( 0 , 0 , 0 ) } ) ; } ) ; currentY -= field . options . length * 20 ; break ; case 'dropdown' : const dropdown = pdfDoc . getForm ( ) . createDropdown ( field . name ) ; dropdown . addOptions ( field . options ) ; dropdown . addToPage ( page , { x : 50 , y : currentY , width : 200 , height : 20 , borderColor : rgb ( 0.5 , 0.5 , 0.5 ) , borderWidth : 1 } ) ; break ; case 'date' : const dateField = pdfDoc . getForm ( ) . createTextField ( field . name ) ; dateField . addToPage ( page , { x : 50 , y : currentY , width : 150 , height : 20 , borderColor : rgb ( 0.5 , 0.5 , 0.5 ) , borderWidth : 1 } ) ; dateField . setText ( 'MM/DD/YYYY' ) ; break ; } // Add help text if provided if ( field . helpText ) { page . drawText ( field . helpText , { x : 370 , y : currentY + 5 , size : 8 , color : rgb ( 0.6 , 0.6 , 0.6 ) , maxWidth : 200 } ) ; } currentY -= 40 ; // Add new page if running out of space if ( currentY < 100 ) { const newPage = pdfDoc . addPage ( [ 612 , 792 ] ) ; currentY = height - 50 ; } } // Add submit button placeholder (text) page . drawText ( 'Please save and email this completed form to: ' + formData . submitEmail , { x : 50 , y : 50 , size : 9 , color : rgb ( 0.3 , 0.3 , 0.3 ) } ) ; const pdfBytes = await pdfDoc . save ( ) ; fs . writeFileSync ( outputPath , pdfBytes ) ; return outputPath ; } Workflow 2: Generate HTML Form Purpose: Create interactive HTML form with client-side validation Steps: Define form structure and fields Generate HTML markup Add CSS styling for professional appearance Implement JavaScript validation Handle form submission Add accessibility features (ARIA labels, keyboard navigation) Make responsive for mobile devices Test across browsers Implementation: function generateHTMLForm ( formData , outputPath ) { const html = `

${ formData . title }
Form submitted successfully! Thank you.

${ formData . title }

${ formData . instructions ? `

${ formData . instructions }

` : '' }
${ formData . fields . map ( field => generateFieldHTML ( field ) ) . join ( '\n' ) }

; fs . writeFileSync ( outputPath , html , 'utf8' ) ; return outputPath ; } function generateFieldHTML ( field ) { const requiredAttr = field . required ? 'required' : '' ; const requiredLabel = field . required ? '<span class="required">*</span>' : '' ; switch ( field . type ) { case 'text' : case 'email' : case 'number' : case 'tel' : case 'date' : return

${ field . helpText ? `
${ field . helpText }
` : '' }
${ field . errorMessage || 'This field is required' }

; case 'textarea' : return

${ field . helpText ? `
${ field . helpText }
` : '' }
This field is required

; case 'select' : return

${ field . helpText ? `
${ field . helpText }
` : '' }
Please select an option

; case 'checkbox' : return

${ field . options . map ( ( opt , idx ) => `
` ) . join ( '\n' ) }
${ field . helpText ? `
${ field . helpText }
` : '' }

; case 'radio' : return

${ field . options . map ( ( opt , idx ) => `
` ) . join ( '\n' ) }
${ field . helpText ? `
${ field . helpText }
` : '' }
Please select an option

; default : return '' ; } } function generateValidationScript ( formData ) { return const form = document.getElementById('mainForm'); const submitBtn = document.getElementById('submitBtn'); const successMessage = document.getElementById('successMessage'); // Validation rules const validationRules = { email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, phone: /^[\d\s\-\(\)]+$/ }; // Real-time validation form.addEventListener('input', (e) => { validateField(e.target); }); // Form submission form.addEventListener('submit', async (e) => { e.preventDefault(); // Validate all fields let isValid = true; const fields = form.querySelectorAll('input, textarea, select'); fields.forEach(field => { if (!validateField(field)) { isValid = false; } }); if (!isValid) { return; } // Disable submit button submitBtn.disabled = true; submitBtn.textContent = 'Submitting...'; try { // Collect form data const formData = new FormData(form); const data = Object.fromEntries(formData); // Submit to server ${ formData . submitUrl ? const response = await fetch(' ${ formData . submitUrl } ', { method: ' ${ formData . method || 'POST' } ', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); if (response.ok) { successMessage.style.display = 'block'; form.reset(); } else { alert('Submission failed. Please try again.'); } : // No submit URL - just show success console.log('Form data:', data); successMessage.style.display = 'block'; form.reset(); } } catch (error) { alert('An error occurred. Please try again.'); console.error(error); } finally { submitBtn.disabled = false; submitBtn.textContent = 'Submit'; } }); function validateField(field) { const errorEl = document.getElementById(field.name + '-error'); if (!errorEl) return true; let isValid = true; let errorMessage = ''; // Required check if (field.hasAttribute('required') && !field.value.trim()) { isValid = false; errorMessage = 'This field is required'; } // Email validation if (field.type === 'email' && field.value && !validationRules.email.test(field.value)) { isValid = false; errorMessage = 'Please enter a valid email address'; } // Pattern validation if (field.hasAttribute('pattern') && field.value) { const pattern = new RegExp(field.getAttribute('pattern')); if (!pattern.test(field.value)) { isValid = false; errorMessage = 'Please enter a valid value'; } } // Update UI if (isValid) { field.classList.remove('invalid'); errorEl.classList.remove('visible'); } else { field.classList.add('invalid'); errorEl.textContent = errorMessage; errorEl.classList.add('visible'); } return isValid; } ; } Workflow 3: Survey/Questionnaire Generator Purpose: Create comprehensive surveys with multiple question types and logic Steps: Define survey structure and sections Add various question types (multiple choice, rating, text, etc.) Implement conditional logic (skip patterns) Add validation rules Configure answer choices and scales Design results collection and analysis Generate survey in preferred format Set up response tracking Implementation: async function generateSurvey ( surveyData , outputPath ) { const survey = { title : surveyData . title , description : surveyData . description , sections : surveyData . sections . map ( section => ( { title : section . title , questions : section . questions . map ( ( q , idx ) => ( { id : q ${ section . id } _ ${ idx + 1 } , type : q . type , text : q . text , required : q . required !== false , options : q . options , validation : q . validation , conditionalLogic : q . conditionalLogic } ) ) } ) ) , settings : { allowAnonymous : surveyData . allowAnonymous !== false , showProgress : surveyData . showProgress !== false , randomizeQuestions : surveyData . randomizeQuestions || false , allowMultipleSubmissions : surveyData . allowMultipleSubmissions || false } } ; // Generate HTML survey const html = generateSurveyHTML ( survey ) ; fs . writeFileSync ( outputPath , html , 'utf8' ) ; return { surveyPath : outputPath , questionCount : survey . sections . reduce ( ( sum , s ) => sum + s . questions . length , 0 ) , settings : survey . settings } ; } function generateSurveyHTML ( survey ) { return

${ survey . title }

${ survey . title }

${ survey . description }

${ survey . settings . showProgress ? `
` : '' }
${ survey . sections . map ( section => `

${ section . title }

${ section . questions . map ( q => generateQuestionHTML ( q ) ) . join ( '\n' ) }
` ) . join ( '\n' ) }

; } function generateQuestionHTML ( question ) { const requiredMark = question . required ? '<span class="required-indicator">*</span>' : '' ; switch ( question . type ) { case 'multipleChoice' : return

${ question . text } ${ requiredMark }
${ question . options . map ( ( opt , idx ) => `
` ) . join ( '\n' ) }

; case 'rating' : const scale = question . scale || 5 ; return

${ question . text } ${ requiredMark }
${ Array . from ( { length : scale } , ( _ , i ) => i + 1 ) . map ( num => `
${ num }
` ) . join ( '\n' ) }

; case 'text' : return

${ question . text } ${ requiredMark }

; case 'checkbox' : return

${ question . text } ${ requiredMark }
${ question . options . map ( ( opt , idx ) => `
` ) . join ( '\n' ) }

; default : return '' ; } } function generateSurveyScript ( survey ) { return function selectRating(questionId, value) { // Remove previous selection const container = document.querySelector(`[data-question-id="\${questionId}"]`); container.querySelectorAll('.rating-option').forEach(opt => { opt.classList.remove('selected'); }); // Add new selection event.target.classList.add('selected'); document.getElementById(questionId).value = value; } // Form submission document.getElementById('surveyForm').addEventListener('submit', async (e) => { e.preventDefault(); const formData = new FormData(e.target); const responses = Object.fromEntries(formData); console.log('Survey responses:', responses); // Submit to server or save locally alert('Thank you for completing the survey!'); e.target.reset(); }); // Progress tracking ${ survey . settings . showProgress ? const questions = document . querySelectorAll ( '.question' ) ; const progressFill = document . getElementById ( 'progressFill' ) ; document . addEventListener ( 'input' , updateProgress ) ; function updateProgress ( ) { let answered = 0 ; questions . forEach ( q => { const inputs = q . querySelectorAll ( 'input, textarea' ) ; const hasAnswer = Array . from ( inputs ) . some ( input => { if ( input . type === 'radio' || input . type === 'checkbox' ) { return input . checked ; } return input . value . trim ( ) !== '' ; } ) ; if ( hasAnswer ) answered ++ ; } ); const progress = (answered / questions.length) * 100; progressFill.style.width = progress + '%'; } : '' } ` ; } Workflow 4: Form Data Processing Purpose: Handle form submissions and process collected data Steps: Set up submission endpoint Validate submitted data Process and sanitize inputs Store data in database or spreadsheet Send confirmation email Generate summary reports Export data for analysis Workflow 5: Multi-Page Form with Progress Purpose: Create long forms split into multiple pages with progress tracking Steps: Divide form into logical sections Create page navigation Implement progress bar Save progress between pages Add validation at each step Allow going back to edit Submit all data at the end Quick Reference Action Command/Trigger PDF fillable form "create fillable PDF form" HTML form "generate HTML form with [fields]" Survey "build survey about [topic]" Contact form "create contact form" Registration form "make registration form" Feedback form "generate feedback survey" Multi-step form "create multi-page form" Best Practices Clear Labels: Use descriptive, concise labels for all fields Logical Grouping: Group related fields together Required Fields: Clearly mark required fields with asterisks Help Text: Provide guidance for complex fields Validation: Implement both client-side and server-side validation Error Messages: Show clear, helpful error messages Accessibility: Include ARIA labels, keyboard navigation Mobile Responsive: Ensure forms work on all devices Progress Indicators: Show progress for long forms Save Progress: Allow users to save and resume Confirmation: Show success message after submission Security: Use CSRF protection, sanitize inputs Common Patterns Contact Form: { fields : [ { name : 'name' , type : 'text' , label : 'Full Name' , required : true } , { name : 'email' , type : 'email' , label : 'Email' , required : true } , { name : 'phone' , type : 'tel' , label : 'Phone Number' } , { name : 'subject' , type : 'text' , label : 'Subject' , required : true } , { name : 'message' , type : 'textarea' , label : 'Message' , required : true } ] } Event Registration: { fields : [ { name : 'attendeeName' , type : 'text' , required : true } , { name : 'email' , type : 'email' , required : true } , { name : 'ticketType' , type : 'select' , options : [ 'General' , 'VIP' ] , required : true } , { name : 'dietaryRestrictions' , type : 'checkbox' , options : [ 'Vegetarian' , 'Vegan' , 'Gluten-Free' ] } , { name : 'specialRequests' , type : 'textarea' } ] } Dependencies Install required packages: npm install pdf-lib

For PDF forms

npm install express

For form submission handling

npm install validator

For input validation

npm install nodemailer

For email confirmations

Error Handling Validation Errors: Show specific field-level errors Network Errors: Handle submission failures gracefully Data Loss: Auto-save progress to prevent data loss Browser Compatibility: Test across different browsers Advanced Features Conditional Logic: conditionalLogic : { showIf : { field : 'employment' , value : 'employed' } , hideIf : { field : 'student' , value : 'yes' } } File Upload: { name : 'resume' , type : 'file' , accept : '.pdf,.doc,.docx' , maxSize : 5242880 // 5MB } Auto-Save: setInterval ( ( ) => { const formData = new FormData ( form ) ; localStorage . setItem ( 'formDraft' , JSON . stringify ( Object . fromEntries ( formData ) ) ) ; } , 30000 ) ;

返回排行榜